package domain

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/mars/pkg/errors"
)

// OrderStatus 订单状态枚举
type OrderStatus string

const (
	OrderStatusPending   OrderStatus = "pending"   // 待支付
	OrderStatusPaid      OrderStatus = "paid"      // 已支付
	OrderStatusShipped   OrderStatus = "shipped"   // 已发货
	OrderStatusDelivered OrderStatus = "delivered" // 已收货
	OrderStatusCompleted OrderStatus = "completed" // 已完成
	OrderStatusCancelled OrderStatus = "cancelled" // 已取消
	OrderStatusRefunded  OrderStatus = "refunded"  // 已退款
	OrderStatusRefunding OrderStatus = "refunding" // 退款中
)

// PaymentMethod 支付方式枚举
type PaymentMethod string

const (
	PaymentMethodWechat PaymentMethod = "wechat" // 微信支付
	PaymentMethodAlipay PaymentMethod = "alipay" // 支付宝
)

// VipType VIP类型枚举
type VipType string

const (
	VipTypeMonthly VipType = "monthly" // 月度会员
	VipTypeYearly  VipType = "yearly"  // 年度会员
)

// DiscountType 折扣类型枚举
type DiscountType string

const (
	DiscountTypePercent DiscountType = "percent" // 百分比折扣
	DiscountTypeAmount  DiscountType = "amount"  // 固定金额折扣
)

// VipDiscount VIP折扣信息
type VipDiscount struct {
	Type  DiscountType `json:"type" bson:"type"`   // 折扣类型
	Value int          `json:"value" bson:"value"` // 折扣值
}

// OrderItem 订单项
type OrderItem struct {
	ProductID        string       `json:"productId" bson:"productId"`
	ProductName      string       `json:"productName" bson:"productName"`
	ProductImage     string       `json:"productImage" bson:"productImage"`
	ProductType      ProductType  `json:"productType" bson:"productType"`
	OriginalPrice    int          `json:"originalPrice" bson:"originalPrice"`       // 原价（分）
	Price            int          `json:"price" bson:"price"`                       // 实际价格（分）
	Quantity         int          `json:"quantity" bson:"quantity"`                 // 数量
	OriginalSubtotal int          `json:"originalSubtotal" bson:"originalSubtotal"` // 原小计（分）
	Subtotal         int          `json:"subtotal" bson:"subtotal"`                 // 实际小计（分）
	HasVipDiscount   bool         `json:"hasVipDiscount" bson:"hasVipDiscount"`     // 是否有VIP折扣
	VipDiscount      *VipDiscount `json:"vipDiscount,omitempty" bson:"vipDiscount,omitempty"`
	TicketType       string       `json:"ticketType,omitempty" bson:"ticketType,omitempty"` // 门票类型
}

// Order 订单实体
type Order struct {
	ID             string        `json:"_id,omitempty" bson:"_id,omitempty"`
	OrderNo        string        `json:"orderNo" bson:"orderNo"`
	OpenID         string        `json:"openid" bson:"openid"`
	Phone          string        `json:"phone" bson:"phone"`
	Items          []OrderItem   `json:"items" bson:"items"`
	OriginalAmount int           `json:"originalAmount" bson:"originalAmount"` // 原始金额（分）
	DiscountAmount int           `json:"discountAmount" bson:"discountAmount"` // 折扣金额（分）
	TotalAmount    int           `json:"totalAmount" bson:"totalAmount"`       // 实际支付金额（分）
	PaymentMethod  PaymentMethod `json:"paymentMethod" bson:"paymentMethod"`
	PaymentTime    *int64        `json:"paymentTime,omitempty" bson:"paymentTime,omitempty"`
	Status         OrderStatus   `json:"status" bson:"status"`
	IsVipOrder     bool          `json:"isVipOrder" bson:"isVipOrder"`
	VipInfo        *VipInfo      `json:"vipInfo,omitempty" bson:"vipInfo,omitempty"`
	Address        *Address      `json:"address,omitempty" bson:"address,omitempty"` // 实物商品才有收货地址
	Remark         string        `json:"remark,omitempty" bson:"remark,omitempty"`
	CreateTime     int64         `json:"createTime" bson:"createTime"`
	UpdateTime     int64         `json:"updateTime" bson:"updateTime"`
}

// OrderQueryParams 订单查询参数
type OrderQueryParams struct {
	PaginationParams
	SortParams
	Status         OrderStatus   `json:"status,omitempty"`
	PaymentMethod  PaymentMethod `json:"paymentMethod,omitempty"`
	IsVipOrder     *bool         `json:"isVipOrder,omitempty"`
	ProductType    ProductType   `json:"productType,omitempty"`
	Keyword        string        `json:"keyword,omitempty"`        // 搜索关键字（订单号、用户openid、商品名称）
	StartTime      *int64        `json:"startTime,omitempty"`      // 开始时间
	EndTime        *int64        `json:"endTime,omitempty"`        // 结束时间
	MinAmount      *int          `json:"minAmount,omitempty"`      // 最小金额
	MaxAmount      *int          `json:"maxAmount,omitempty"`      // 最大金额
	HasVipDiscount *bool         `json:"hasVipDiscount,omitempty"` // 是否有VIP折扣
}

// OrderStats 订单统计信息
type OrderStats struct {
	TotalOrders         int64            `json:"totalOrders"`         // 总订单数
	TotalAmount         int64            `json:"totalAmount"`         // 总金额（分）
	TotalDiscountAmount int64            `json:"totalDiscountAmount"` // 总折扣金额（分）
	OrdersByStatus      map[string]int64 `json:"ordersByStatus"`      // 按状态统计
	OrdersByPayment     map[string]int64 `json:"ordersByPayment"`     // 按支付方式统计
	OrdersByType        map[string]int64 `json:"ordersByType"`        // 按商品类型统计
	VipOrderCount       int64            `json:"vipOrderCount"`       // VIP订单数
	VipDiscountAmount   int64            `json:"vipDiscountAmount"`   // VIP折扣总金额
	AvgOrderAmount      int              `json:"avgOrderAmount"`      // 平均订单金额（分）
	TopProducts         []ProductStat    `json:"topProducts"`         // 热销商品
}

// ProductStat 商品统计
type ProductStat struct {
	ProductID   string `json:"productId"`
	ProductName string `json:"productName"`
	OrderCount  int64  `json:"orderCount"`  // 订单数
	TotalAmount int64  `json:"totalAmount"` // 总金额
}

// OrderValidator 订单验证器
type OrderValidator struct {
	paginationValidator *PaginationValidator
	idValidator         *IDValidator
	dateValidator       *DateValidator
	stringValidator     *StringValidator
	enumValidator       *EnumValidator
	sortValidator       *SortValidator
}

// NewOrderValidator 创建订单验证器
func NewOrderValidator() *OrderValidator {
	return &OrderValidator{
		paginationValidator: NewPaginationValidator(1000),
		idValidator:         NewIDValidator("order ID", 1, 128),
		dateValidator:       NewDateValidator(),
		stringValidator:     NewStringValidator("keyword", 100, false),
		enumValidator: NewEnumValidator("status", []string{
			string(OrderStatusPending), string(OrderStatusPaid), string(OrderStatusShipped),
			string(OrderStatusDelivered), string(OrderStatusCompleted), string(OrderStatusCancelled),
			string(OrderStatusRefunded), string(OrderStatusRefunding),
		}, false),
		sortValidator: NewSortValidator([]string{
			"createTime", "updateTime", "totalAmount", "paymentTime", "orderNo",
		}),
	}
}

// ValidateOrderID 验证订单ID
func (ov *OrderValidator) ValidateOrderID(cxt *gin.Context, paramName string) (string, error) {
	return ov.idValidator.ValidateFromParam(cxt, paramName)
}

// ValidateOrderStatus 验证订单状态
func (ov *OrderValidator) ValidateOrderStatus(cxt *gin.Context, paramName string) (OrderStatus, error) {
	status := cxt.Param(paramName)
	if status == "" {
		status = cxt.Query(paramName)
	}

	if status == "" {
		return "", errors.New(http.StatusBadRequest, "order status is required")
	}

	err := ov.enumValidator.Validate(status)
	if err != nil {
		return "", err
	}

	return OrderStatus(status), nil
}

// ValidatePaymentMethod 验证支付方式
func (ov *OrderValidator) ValidatePaymentMethod(value string) error {
	if value == "" {
		return nil
	}

	validMethods := []string{string(PaymentMethodWechat), string(PaymentMethodAlipay)}
	for _, method := range validMethods {
		if value == method {
			return nil
		}
	}

	return errors.New(http.StatusBadRequest, "invalid payment method, must be one of: wechat, alipay")
}

// ValidateProductTypeValue 验证商品类型值
func (ov *OrderValidator) ValidateProductTypeValue(value string) (ProductType, error) {
	if value == "" {
		return "", nil
	}

	validTypes := []string{string(ProductTypeVIP), string(ProductTypeTicket), string(ProductTypePhysical)}
	for _, validType := range validTypes {
		if value == validType {
			return ProductType(value), nil
		}
	}

	return "", errors.New(http.StatusBadRequest, "invalid product type, must be one of: vip, ticket, physical")
}

// ValidateQueryParams 验证查询参数
func (ov *OrderValidator) ValidateQueryParams(cxt *gin.Context) (OrderQueryParams, error) {
	// 验证分页参数
	pagination, err := ov.paginationValidator.ValidateAndParse(cxt)
	if err != nil {
		return OrderQueryParams{}, err
	}

	// 验证排序参数
	sort, err := ov.sortValidator.ValidateAndParse(cxt)
	if err != nil {
		return OrderQueryParams{}, err
	}

	params := OrderQueryParams{
		PaginationParams: pagination,
		SortParams:       sort,
	}

	// 验证状态参数
	statusStr := cxt.Query("status")
	if statusStr != "" {
		err = ov.enumValidator.Validate(statusStr)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.Status = OrderStatus(statusStr)
	}

	// 验证支付方式
	paymentMethodStr := cxt.Query("paymentMethod")
	if paymentMethodStr != "" {
		err = ov.ValidatePaymentMethod(paymentMethodStr)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.PaymentMethod = PaymentMethod(paymentMethodStr)
	}

	// 验证VIP订单标识
	isVipOrderStr := cxt.Query("isVipOrder")
	if isVipOrderStr != "" {
		isVipOrder, err := strconv.ParseBool(isVipOrderStr)
		if err != nil {
			return OrderQueryParams{}, errors.New(http.StatusBadRequest, "invalid isVipOrder parameter")
		}
		params.IsVipOrder = &isVipOrder
	}

	// 验证商品类型
	productTypeStr := cxt.Query("productType")
	if productTypeStr != "" {
		productType, err := ov.ValidateProductTypeValue(productTypeStr)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.ProductType = productType
	}

	// 验证搜索关键字
	keyword := cxt.Query("keyword")
	if keyword != "" {
		err = ov.stringValidator.Validate(keyword)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.Keyword = keyword
	}

	// 验证时间范围
	startTimeStr := cxt.Query("startTime")
	if startTimeStr != "" {
		startTime, err := ov.dateValidator.ValidateDateRequired(startTimeStr)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.StartTime = &startTime
	}

	endTimeStr := cxt.Query("endTime")
	if endTimeStr != "" {
		endTime, err := ov.dateValidator.ValidateDateRequired(endTimeStr)
		if err != nil {
			return OrderQueryParams{}, err
		}
		params.EndTime = &endTime
	}

	// 验证金额范围
	minAmountStr := cxt.Query("minAmount")
	if minAmountStr != "" {
		minAmount, err := strconv.Atoi(minAmountStr)
		if err != nil || minAmount < 0 {
			return OrderQueryParams{}, errors.New(http.StatusBadRequest, "invalid minAmount parameter")
		}
		params.MinAmount = &minAmount
	}

	maxAmountStr := cxt.Query("maxAmount")
	if maxAmountStr != "" {
		maxAmount, err := strconv.Atoi(maxAmountStr)
		if err != nil || maxAmount < 0 {
			return OrderQueryParams{}, errors.New(http.StatusBadRequest, "invalid maxAmount parameter")
		}
		params.MaxAmount = &maxAmount
	}

	// 验证VIP折扣标识
	hasVipDiscountStr := cxt.Query("hasVipDiscount")
	if hasVipDiscountStr != "" {
		hasVipDiscount, err := strconv.ParseBool(hasVipDiscountStr)
		if err != nil {
			return OrderQueryParams{}, errors.New(http.StatusBadRequest, "invalid hasVipDiscount parameter")
		}
		params.HasVipDiscount = &hasVipDiscount
	}

	return params, nil
}

// ValidateUpdateStatusRequest 验证状态更新请求
func (ov *OrderValidator) ValidateUpdateStatusRequest(status OrderStatus) error {
	// 管理端可以更新的状态
	validStatuses := []OrderStatus{
		OrderStatusShipped, OrderStatusDelivered, OrderStatusCompleted,
		OrderStatusRefunded, OrderStatusRefunding,
	}

	for _, validStatus := range validStatuses {
		if status == validStatus {
			return nil
		}
	}

	return errors.New(http.StatusBadRequest, "invalid status for admin update, allowed: shipped, delivered, completed, refunded, refunding")
}

// ValidateRefundRequest 验证退款请求
func (ov *OrderValidator) ValidateRefundRequest(reason string, amount *int) error {
	if reason == "" {
		return errors.New(http.StatusBadRequest, "refund reason is required")
	}

	if len(reason) > 500 {
		return errors.New(http.StatusBadRequest, "refund reason must not exceed 500 characters")
	}

	if amount != nil && *amount <= 0 {
		return errors.New(http.StatusBadRequest, "refund amount must be greater than 0")
	}

	return nil
}

// ValidateSearchKeyword 验证搜索关键字
func (ov *OrderValidator) ValidateSearchKeyword(cxt *gin.Context) (string, error) {
	keyword := cxt.Query("keyword")
	if keyword == "" {
		return "", errors.New(http.StatusBadRequest, "search keyword is required")
	}

	err := ov.stringValidator.Validate(keyword)
	if err != nil {
		return "", err
	}

	return keyword, nil
}

// OrderGateway 订单网关接口
type OrderGateway interface {
	GetOrderList(ctx interface{}, params OrderQueryParams) ([]Order, int64, error)
	GetOrder(ctx interface{}, orderID string) (*Order, error)
	UpdateOrderStatus(ctx interface{}, orderID string, status OrderStatus) error
	ProcessRefund(ctx interface{}, orderID string, reason string, amount *int) error
	GetOrderStats(ctx interface{}) (*OrderStats, error)
	SearchOrders(ctx interface{}, keyword string) ([]Order, error)
	GetOrdersByStatus(ctx interface{}, status OrderStatus) ([]Order, error)
	GetOrdersByPaymentMethod(ctx interface{}, paymentMethod PaymentMethod) ([]Order, error)
	GetVipOrders(ctx interface{}) ([]Order, error)
	ExportOrders(ctx interface{}, params OrderQueryParams) ([]Order, error)
}
